package org.visionlibrary.image.geomtric.model;

import org.visionlibrary.image.geomtric.util.Utils;


public class Point2d {
	public final double x;
	public final double y;

	public Point2d() {
		x = 0;
		y = 0;
	}

	public Point2d(double x, double y) {
		this.x = x;
		this.y = y;
	}

	public Point2d(Point2d p) {
		this.x = p.x;
		this.y = p.y;
	}

	public double getX() {
		return x;
	}
	
	public double getY() {
		return y;
	}

	public double distance(Point2d p) {
		return Point2d.distance(this, p);
	}

	public static double distance(Point2d p1, Point2d p2) {
		return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y)
				* (p1.y - p2.y));
	}

	public static Point2d copy(Point2d point) {
		return new Point2d(point.x, point.y);
	}

	public static Point2d multiply(Point2d point, double value) {
		return new Point2d(point.x * value, point.y * value);
	}

	public static Point2d move(Point2d start, double dx, double dy) {
		return new Point2d(start.x + dx, start.y + dy);
	}

	public static Point2d middle(Point2d p1, Point2d p2) {
		return new Point2d((p1.x + p2.x) / 2.0d, (p1.y + p2.y) / 2.0d);
	}

	public static Point2d rotate(Point2d point, Point2d origin, double angle) {
		Point2d rotated = rotate(new Point2d(point.x - origin.x, point.y
				- origin.y), angle);
		return new Point2d(rotated.x + origin.x, rotated.y + origin.y);
	}

	public static Point2d rotate(Point2d point, double angle) {
		double sinus = Math.sin(angle);
		double cosinus = Math.cos(angle);
		double nx = point.x * cosinus - point.y * sinus;
		double ny = point.y * cosinus + point.x * sinus;
		return new Point2d(nx, ny);
	}

	public int getXAsInt() {
		return (int) Math.round(x);
	}

	public int getYAsInt() {
		return (int) Math.round(y);
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Point2d) {
			Point2d point = (Point2d) obj;
			return Double.compare(Utils.roundDouble(this.x, 5), Utils.roundDouble(point.x, 5)) == 0
					&& Double.compare(Utils.roundDouble(this.y, 5), Utils.roundDouble(point.y, 5)) == 0;
		}

		return false;
	}

	@Override
	public String toString() {
		return "Point2d (" + x + ":" + y + ")";
	}
}
